package jdos.hardware;

public class VGA_gfx {

    public static short index;
    public static short set_reset;
    public static short enable_set_reset;
    public static short read_map_select;
    public static short bit_mask;
    
    private static IoHandler.IO_WriteHandler write_p3ce = new IoHandler.IO_WriteHandler() {
        public void call(/*Bitu*/int port, /*Bitu*/int val, /*Bitu*/int iolen) {
	        index=(short)(val & 0x0f);
        }
    };

    private static IoHandler.IO_ReadHandler read_p3ce = new IoHandler.IO_ReadHandler() {
        public /*Bitu*/int call(/*Bitu*/int port, /*Bitu*/int iolen) {
	        return index;
        }
    };

    private static IoHandler.IO_WriteHandler write_p3cf = new IoHandler.IO_WriteHandler() {
        public void call(/*Bitu*/int port, /*Bitu*/int val, /*Bitu*/int iolen) {
            switch (index) {
            case 0:	/* Set/Reset Register */
                set_reset=(short)(val & 0x0f);
                break;
            case 1: /* Enable Set/Reset Register */
                enable_set_reset=(short)(val & 0x0f);
                break;
            case 2: /* Color Compare Register */
                VGA.vga.config.color_compare=(short)(val & 0xf);
        //		LOG_DEBUG("Color Compare = %2X",val);
                break;
            case 3: /* Data Rotate */
                VGA.vga.config.raster_op=(short)((val>>3) & 3);
                break;
            case 4: /* Read Map Select Register */
                /*	0-1	number of the plane Read Mode 0 will read from */
                read_map_select=(short)(val & 0x03);
                break;
            case 5: /* Mode Register */
                VGA.vga.config.write_mode=(short)(val & 3);
                VGA.vga.config.read_mode=(short)((val >> 3) & 1);
        //		LOG_DEBUG("Write Mode %d Read Mode %d val %d",VGA.vga.config.write_mode,VGA.vga.config.read_mode,val);
                /*
                    0-1	Write Mode: Controls how data from the CPU is transformed before
                        being written to display memory:
                        0:	Mode 0 works as a Read-Modify-Write operation.
                            First a read access loads the data latches of the VGA with the
                            value in video memory at the addressed location. Then a write
                            access will provide the destination address and the CPU data
                            byte. The data written is modified by the function code in the
                            Data Rotate register (3CEh index 3) as a function of the CPU
                            data and the latches, then data is rotated as specified by the
                            same register.
                        1:	Mode 1 is used for video to video transfers.
                            A read access will load the data latches with the contents of
                            the addressed byte of video memory. A write access will write
                            the contents of the latches to the addressed byte. Thus a single
                            MOVSB instruction can copy all pixels in the source address byte
                            to the destination address.
                        2:	Mode 2 writes a color to all pixels in the addressed byte of
                            video memory. Bit 0 of the CPU data is written to plane 0 et
                            cetera. Individual bits can be enabled or disabled through the
                            Bit Mask register (3CEh index 8).
                        3:	Mode 3 can be used to fill an area with a color and pattern. The
                            CPU data is rotated according to 3CEh index 3 bits 0-2 and anded
                            with the Bit Mask Register (3CEh index 8). For each bit in the
                            result the corresponding pixel is set to the color in the
                            Set/Reset Register (3CEh index 0 bits 0-3) if the bit is set and
                            to the contents of the processor latch if the bit is clear.
                */
                break;
            case 7: /* Color Don't Care Register */
                VGA.vga.config.color_dont_care=(short)(val & 0xf);
        //		LOG_DEBUG("Color don't care = %2X",val);
                break;
            case 8: /* Bit Mask Register */
                bit_mask=(short)val;
        //		LOG_DEBUG("Bit mask %2X",val);
                /*
                    0-7	Each bit if set enables writing to the corresponding bit of a byte in
                        display memory.
                */
                break;
            default:
            }
        }
    };

    private static IoHandler.IO_ReadHandler read_p3cf = new IoHandler.IO_ReadHandler() {
        public /*Bitu*/int call(/*Bitu*/int port, /*Bitu*/int iolen) {
            switch (index) {
            case 0:	/* Set/Reset Register */
                return set_reset;
            case 1: /* Enable Set/Reset Register */
                return enable_set_reset;
            case 4: /* Read Map Select Register */
                return read_map_select;
            case 8: /* Bit Mask Register */
                return bit_mask;
            default:
            }
            return 0;	/* Compiler happy */
        }
    };

    static public void VGA_SetupGFX() {
        //if (Dosbox.IS_EGAVGA_ARCH()) {
        IoHandler.IO_RegisterWriteHandler(0x3ce,write_p3ce,IoHandler.IO_MB);
        IoHandler.IO_RegisterWriteHandler(0x3cf,write_p3cf,IoHandler.IO_MB);
        //if (Dosbox.IS_VGA_ARCH()) {
        IoHandler.IO_RegisterReadHandler(0x3ce,read_p3ce,IoHandler.IO_MB);
        IoHandler.IO_RegisterReadHandler(0x3cf,read_p3cf,IoHandler.IO_MB);
        //}
        //}
    }
}
